﻿using DotNetty.Buffers;
using DotNetty.Transport.Channels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NetC100K.Handler
{
    /// <summary>
    /// 函数调用流程
    /// 打开：HandlerAdded => ChannelRegistered => ChannelActive
    /// 读取（操作循环）：ChannelRead => ChannelReadComplete
    /// 结束：ChannelInactive => ChannelUnregistered => HandlerRemoved
    /// </summary>
    public class SessionHandler : ChannelDuplexHandler
    {
        private ILogger _logger;

        private ConcurrentDictionary<string, IChannel> _channels;

        public SessionHandler(ConcurrentDictionary<string, IChannel> channels, ILogger logger)
        {
            _logger = logger;
            _channels = channels;
        }

        public override Task ConnectAsync(IChannelHandlerContext context, EndPoint remoteAddress, EndPoint localAddress)
        {
            _logger.LogInformation($"ConnectAsync开始连接，ID：{context.Channel.Id.AsShortText()}，Local：{localAddress}，Remote：{remoteAddress}");
            return base.ConnectAsync(context, remoteAddress, localAddress);
        }

        /// <summary>
        /// 客户端连接触发3
        /// </summary>
        /// <param name="context"></param>
        public override void ChannelActive(IChannelHandlerContext context)
        {
            if (!_channels.TryAdd(context.Channel.Id.AsLongText(), context.Channel))
            {
                _logger.LogWarning($"HandlerAdded添加失败，连接ID：{context.Channel.Id.AsShortText()}");
            }
            else
            {
                _logger.LogInformation($"HandlerAdded添加成功，ID：{context.Channel.Id.AsShortText()}，Local：{context.Channel.LocalAddress}，Remote：{context.Channel.RemoteAddress}");
            }
        }

        /// <summary>
        /// 客户端断开触发1
        /// </summary>
        /// <param name="context"></param>
        public override void ChannelInactive(IChannelHandlerContext context) { }

        /// <summary>
        /// 消息读取触发1
        /// </summary>
        /// <param name="context"></param>
        /// <param name="message"></param>
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var byteBuffer = message as IByteBuffer;
            if (byteBuffer.HasArray)
            {
                int length = byteBuffer.ReadableBytes;
                byte[] array = new byte[length];
                byteBuffer.ReadBytes(array);
                if (message != null)
                    _logger.LogDebug($"ChannelRead，ID：{context.Channel.Id.AsShortText()}，message：{System.Text.Encoding.UTF8.GetString(array, 0, length)}");
            }
        }

        /// <summary>
        /// 消息读取触发2
        /// </summary>
        /// <param name="context"></param>
        public override void ChannelReadComplete(IChannelHandlerContext context) { }

        /// <summary>
        /// 客户端连接触发2
        /// </summary>
        /// <param name="context"></param>
        public override void ChannelRegistered(IChannelHandlerContext context) { }

        /// <summary>
        /// 客户端断开触发2
        /// </summary>
        /// <param name="context"></param>
        public override void ChannelUnregistered(IChannelHandlerContext context) { }

        /// <summary>
        /// 客户端连接触发1
        /// </summary>
        /// <param name="context"></param>
        public override void HandlerAdded(IChannelHandlerContext context) { }

        /// <summary>
        /// 客户端断开触发3
        /// </summary>
        /// <param name="context"></param>
        public override void HandlerRemoved(IChannelHandlerContext context)
        {
            if (!_channels.TryRemove(context.Channel.Id.AsLongText(), out IChannel channel))
            {
                _logger.LogWarning($"HandlerRemoved删除失败，ID：{context.Channel.Id.AsShortText()}");
            }
            else
            {
                _logger.LogInformation($"HandlerRemoved删除成功，ID：{context.Channel.Id.AsShortText()}，Local：{context.Channel.LocalAddress}，Remote：{context.Channel.RemoteAddress}");
            }
        }
    }
}
